package projet.dao.jpa;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.TemporalType;
import javax.persistence.TypedQuery;

import projet.dao.CourseDAOInterface;
import projet.entity.Course;
import projet.entity.Session;

public class JPACourseDAO implements CourseDAOInterface {

	@Override
	public List<Course> getList() {
		List<Course> courses = null;

		EntityManager em = JPAUtil.getEntityManagerFactory().createEntityManager();
		try {
			em.getTransaction().begin();

			TypedQuery<Course> query = em.createNamedQuery("Course.findAll", Course.class);
			courses = query.getResultList();

			em.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
			try { em.getTransaction().rollback(); } catch (Exception e2) { e2.printStackTrace(); }
		} finally {
			try { em.close(); } catch (Exception e2) { e2.printStackTrace(); }
		}

		return courses;
	}

	@Override
	public Course getById(String code) {
		Course course = null;

		EntityManager em = JPAUtil.getEntityManagerFactory().createEntityManager();
		try {
			em.getTransaction().begin();

			course = em.find(Course.class, code);

			em.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
			try { em.getTransaction().rollback(); } catch (Exception e2) { e2.printStackTrace(); }
		} finally {
			try { em.close(); } catch (Exception e2) { e2.printStackTrace(); }
		}

		return course;
	}

	@Override
	public void create(Course course) {
		EntityManager em = JPAUtil.getEntityManagerFactory().createEntityManager();
		try {
			em.getTransaction().begin();

			em.persist(course);

			em.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
			try { em.getTransaction().rollback(); } catch (Exception e2) { e2.printStackTrace(); }
		} finally {
			try { em.close(); } catch (Exception e2) { e2.printStackTrace(); }
		}
	}

	@Override
	public void update(Course course) {
		EntityManager em = JPAUtil.getEntityManagerFactory().createEntityManager();
		try {
			em.getTransaction().begin();

			em.merge(course);

			em.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
			try { em.getTransaction().rollback(); } catch (Exception e2) { e2.printStackTrace(); }
		} finally {
			try { em.close(); } catch (Exception e2) { e2.printStackTrace(); }
		}
	}

	@Override
	public void delete(Course course) {
		EntityManager em = JPAUtil.getEntityManagerFactory().createEntityManager();
		try {
			em.getTransaction().begin();

			Course c = em.find(Course.class, course.getCode());
			em.remove(c);

			em.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
			try { em.getTransaction().rollback(); } catch (Exception e2) { e2.printStackTrace(); }
		} finally {
			try { em.close(); } catch (Exception e2) { e2.printStackTrace(); }
		}
	}

	@Override
	public List<Session> getSessions(String code) {
		List<Session> sessions = null;

		EntityManager em = JPAUtil.getEntityManagerFactory().createEntityManager();
		try {
			em.getTransaction().begin();

			TypedQuery<Session> query = em.createNamedQuery("Course.findSessions", Session.class);
			query.setParameter("code", code);
			sessions = query.getResultList();

			em.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
			try { em.getTransaction().rollback(); } catch (Exception e2) { e2.printStackTrace(); }
		} finally {
			try { em.close(); } catch (Exception e2) { e2.printStackTrace(); }
		}

		return sessions;
	}

	@Override
	public List<Session> getSessionsFuture(String code) {
		List<Session> sessions = null;

		EntityManager em = JPAUtil.getEntityManagerFactory().createEntityManager();
		try {
			em.getTransaction().begin();

			TypedQuery<Session> query = em.createNamedQuery("Course.findSessionsFuture", Session.class);
			query.setParameter("code", code);
			sessions = query.getResultList();

			em.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
			try { em.getTransaction().rollback(); } catch (Exception e2) { e2.printStackTrace(); }
		} finally {
			try { em.close(); } catch (Exception e2) { e2.printStackTrace(); }
		}

		return sessions;
	}

	@Override
	public List<Course> getListByCriteria(String keyword, Long locationId, Date date) {
		List<Course> courses = null;

		EntityManager em = JPAUtil.getEntityManagerFactory().createEntityManager();
		try {
			em.getTransaction().begin();

			TypedQuery<Course> query = null;
			if (keyword == null && locationId == null && date == null) {
				query = em.createNamedQuery("Course.findAll", Course.class);
			} else {
				String queryName = "Course.findAllBy";
				ArrayList<String> criteria = new ArrayList<String>();
				if (keyword != null) {
					criteria.add("Title");
				}
				if (locationId != null) {
					criteria.add("Location");
				}
				if (date != null) {
					criteria.add("Date");
				}
				String criteriaString = null;
				for (String str : criteria) {
					if (criteriaString == null) {
						criteriaString = str;
					} else {
						criteriaString += "And";
						criteriaString += str;
					}
				}
				queryName += criteriaString;
				query = em.createNamedQuery(queryName, Course.class);
				if (keyword != null) {
					query.setParameter("title", "%"+keyword+"%");
				}
				if (locationId != null) {
					query.setParameter("locationId", locationId);
				}
				if (date != null) {
					query.setParameter("date", date, TemporalType.DATE);
				}
			}
			courses = query.getResultList();

			em.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
			try { em.getTransaction().rollback(); } catch (Exception e2) { e2.printStackTrace(); }
		} finally {
			try { em.close(); } catch (Exception e2) { e2.printStackTrace(); }
		}

		return courses;
	}

}
